#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/12/11 23:39
# @Author  : 唐松
# @File    : csv_analysis_params.py
# @Software: PyCharm

import ast
import json
from util_tools.handle_data.csv_handler import read_csv_file
from util_tools.logger_util import logs


def csv_analysis_params(caseinfo: dict):

    """
    将 caseinfo 中定义的 CSV 参数映射到测试用例，实现数据驱动。
    :param caseinfo: 单条测试用例 dict，可能包含 parameters 字段
    :return: 参数化后的用例列表；若失败，则返回原始用例
    """

    # 如果没有 parameters 字段，无需参数化，直接返回原用例
    if 'parameters' not in caseinfo:
        return caseinfo

    # 将原始用例序列化成字符串，方便批量替换
    caseinfo_str = json.dumps(caseinfo, ensure_ascii=False)
    # 存放参数化后的多条用例
    new_caseinfo = []

    # 遍历 parameters 中的每一项（支持多个 CSV 文件）
    for placeholder_key, csv_path in caseinfo['parameters'].items():
        csv_data = read_csv_file(csv_path)  # 读取 CSV 为二维列表
        if len(csv_data) < 2:  # 至少要有表头 + 1 行数据
            logs.error(f"CSV 文件无数据或只有表头: {csv_path}")
            return caseinfo

        header = csv_data[0]  # 第一行作为列名
        rows = csv_data[1:]  # 其余为数据行

        # 1. 校验所有数据行列数是否一致
        if any(len(row) != len(header) for row in rows):
            logs.error(f"CSV 行列长度不一致: {csv_path}")
            return caseinfo

        # 2. 解析占位符 key，支持 "a-b-c" 多列联合
        key_list = str(placeholder_key).split('-')

        # 3. 逐行替换，生成新的用例
        for row in rows:
            temp_case = caseinfo_str
            for col_idx, col_name in enumerate(header):
                if col_name not in key_list:
                    continue  # 当前列不在占位符列表中，跳过

                raw_val = str(row[col_idx]).strip()
                try:
                    # 如果是 JSON 字符串（对象/数组），安全解析后再序列化
                    if raw_val.startswith(('{', '[')):
                        parsed = ast.literal_eval(raw_val)
                        replace_val = json.dumps(parsed, ensure_ascii=False)
                    else:
                        # 普通字符串，直接 JSON 转义后使用
                        replace_val = json.dumps(raw_val, ensure_ascii=False)
                except (ValueError, SyntaxError) as e:
                    logs.error(f"CSV 值解析失败 -> {raw_val}，原因：{e}")
                    continue  # 跳过该行，防止非法代码注入

                # 替换模板中的占位符 "$csv{列名}"
                placeholder = f'"$csv{{{col_name}}}"'
                temp_case = temp_case.replace(placeholder, replace_val)

            # 4. 将替换后的 JSON 字符串还原为 dict
            try:
                new_caseinfo.append(json.loads(temp_case))
            except json.JSONDecodeError as e:
                logs.error(f"CSV 参数化后 JSON 非法，跳过该条用例 -> {e}")
                logs.debug(temp_case)

    # 若参数化成功，返回用例列表；否则返回原始用例
    return new_caseinfo if new_caseinfo else caseinfo

